/************************************
 * 本文件用于封装epoll的相关接口函数
 **************************************/
#pragma once
#include <iostream>
#include <string>

#include <cerrno>
#include <cstring>
#include <cstdlib>

#include <sys/epoll.h>

#include "Socket.hpp"
#include "Log.hpp"

const static int epoll_create_size = 128;
const static int timeout = 1000;
class Epoller
{
public:
    Epoller()
        : _op(0)
        , _timeout(timeout)
    {
        // 在创建该类对象时，直接创建epoll模型，得到epoll_fd
        _epoll_fd = epoll_create(epoll_create_size);
        if (_epoll_fd == -1)
        {
            _log.LogMessage(ClassFile, Error, "epoll_create error, strerror : %s\n", strerror(errno));
            exit(-1);
        }
        _log.LogMessage(ClassFile, Info, "epoll_create success\n");
    }
    ~Epoller()
    {
        close(_epoll_fd); //忘记了，下次要记住
    }
    // 添加一个事件
    bool AddEvent(int fd)
    {
        _op = EPOLL_CTL_ADD;
        epoll_event epevent;
        epevent.events = EPOLLIN;
        epevent.data.fd = fd;
        int ret = epoll_ctl(_epoll_fd, _op, fd, &epevent);
        return !ret;
    }
    // 删除一个事件
    bool DelEvent(int fd)
    {
        _op = EPOLL_CTL_DEL;
        int ret = epoll_ctl(_epoll_fd, _op, fd, nullptr);
        return !ret;
    }
    // epoll等待事件就绪
    int Wait(epoll_event* events, int maxevents)
    {
        return epoll_wait(_epoll_fd, events, maxevents, _timeout);
    }
private:
    int _epoll_fd;
    int _op; // 对一个fd的event的操作：增删改
    int _timeout;
};